package com.yanqu.road.server.manager.activity.signindraw;

import com.yanqu.road.dao.impl.activity.signindraw.CrossSignInDrawItemDataDaoImpl;
import com.yanqu.road.dao.impl.activity.signindraw.CrossSignInDrawUserDataDaoImpl;
import com.yanqu.road.dao.impl.activity.signindraw.SignInDrawConfigDaoImpl;
import com.yanqu.road.dao.impl.activity.signindraw.SignInDrawNoticeDataDaoImpl;
import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.signindraw.SignInDrawConfig;
import com.yanqu.road.entity.activity.signindraw.SignInDrawNoticeData;
import com.yanqu.road.entity.activity.signindraw.config.SignInDrawDrawInfo;
import com.yanqu.road.entity.activity.signindraw.cross.CrossSignInDrawItemData;
import com.yanqu.road.entity.activity.signindraw.cross.CrossSignInDrawUserData;
import com.yanqu.road.entity.enums.eActivityConfigType;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.logic.bussiness.servercenter.ActivityBussiness;
import com.yanqu.road.pb.activity.SignInDrawProto;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.util.*;

public class SignInDrawActivity {

    private ActivityInfo activityInfo;

    Map<String, ActivityConfig> activityConfigMap;

    private SignInDrawConfig config;

    //已出大奖
    private Map<Integer, CrossSignInDrawItemData> itemDataMap;

    //公告
    private List<SignInDrawNoticeData> noticeDataList;

    private final Object drawLock = new Object();

    private Random random = new Random();

    private Map<String, CrossSignInDrawUserData> userDataMap;

    public void init(){

        initConfig();

        noticeDataList = new SignInDrawNoticeDataDaoImpl().getSignInDrawNoticeData(activityInfo.getActivityId(), config.getANNOUNCEMENT_QUANTITY());
        Collections.reverse(noticeDataList);

        itemDataMap = new CrossSignInDrawItemDataDaoImpl().getCrossSignInDrawItemData(activityInfo.getActivityId());

        userDataMap = new CrossSignInDrawUserDataDaoImpl().getCrossSignInDrawUserData(activityInfo.getActivityId());
    }

    public void initConfig() {

        List<Integer> activityIdList = new ArrayList<>();
        activityIdList.add(activityInfo.getActivityId());
        activityConfigMap = ActivityBussiness.getActivityConfigMap(activityIdList).get(activityInfo.getActivityId());

        SignInDrawConfig config = new SignInDrawConfig(activityInfo);

        SignInDrawConfigDaoImpl configDao = new SignInDrawConfigDaoImpl();
        config.setDrawInfoList(configDao.getSignInDrawDrawInfoList(activityInfo.getActivityId()));

        if (activityConfigMap.containsKey(eActivityConfigType.ANNIVERSARY_SUPPLEMENTARY_SIGNATURE_CONSUME.getName())) {
            config.setSIGNATURE_CONSUME(activityConfigMap.get(eActivityConfigType.ANNIVERSARY_SUPPLEMENTARY_SIGNATURE_CONSUME.getName()).getValue());
        }

        if (activityConfigMap.containsKey(eActivityConfigType.ANNIVERSARY_SIGNIN_REWARD.getName())) {
            config.setSIGNIN_REWARD(activityConfigMap.get(eActivityConfigType.ANNIVERSARY_SIGNIN_REWARD.getName()).getIntValue());
        }

        if (activityConfigMap.containsKey(eActivityConfigType.ANNIVERSARY_MAKE_WISH_CONSUME.getName())) {
            config.setMAKE_WISH_CONSUME(activityConfigMap.get(eActivityConfigType.ANNIVERSARY_MAKE_WISH_CONSUME.getName()).getIntValue());
        }

        if (activityConfigMap.containsKey(eActivityConfigType.ANNIVERSARY_ANNOUNCEMENT_QUANTITY.getName())) {
            config.setANNOUNCEMENT_QUANTITY(activityConfigMap.get(eActivityConfigType.ANNIVERSARY_ANNOUNCEMENT_QUANTITY.getName()).getIntValue());
        }

        if (activityConfigMap.containsKey(eActivityConfigType.ANNIVERSARY_SHARING_REWARD.getName())) {
            config.setSHARING_REWARD(activityConfigMap.get(eActivityConfigType.ANNIVERSARY_SHARING_REWARD.getName()).getIntValue());
        }

        if (activityConfigMap.containsKey(eActivityConfigType.ANNIVERSARY_ACTIVE_LIMIT.getName())) {
            config.setACTIVE_LIMIT(activityConfigMap.get(eActivityConfigType.ANNIVERSARY_ACTIVE_LIMIT.getName()).getIntValue());
        }

        if (activityConfigMap.containsKey(eActivityConfigType.ANNIVERSARY_LOTTERY_VIP_LIMIT.getName())) {
            config.setLOTTERY_VIP_LIMIT(activityConfigMap.get(eActivityConfigType.ANNIVERSARY_LOTTERY_VIP_LIMIT.getName()).getValue());
        }

        this.config = config;
    }


    /**
     * 抽奖
     */
    public void draw(long serverId, long playerId, UserBaseInfo baseInfo, int activeDay, String uid) {

        SignInDrawDrawInfo drawDrawInfo;

        CrossSignInDrawUserData userData = getUserData(uid);

        synchronized (drawLock){

            //实物资格
            boolean getIphoneAble = true;

            //活跃度的不足
            if(config.getACTIVE_LIMIT() > 0) {
                if (activeDay < 0 || activeDay > config.getACTIVE_LIMIT()) {
                    getIphoneAble = false;
                }
            }

            //价值档位
            int valueType = config.getValueType(baseInfo.getVipExp());

            //第n天
            int day = (int)getDiffDayNum(activityInfo.getBeginTime() * 1000);

            List<SignInDrawDrawInfo> poolList = new ArrayList<>();
            List<SignInDrawDrawInfo> dayItemList = config.getSignInDrawDrawInfo(day);
            for (SignInDrawDrawInfo drawInfo : dayItemList) {
                if(drawInfo.getLimit() > 0){
                    //是否有资格抽大奖
                    if(!getIphoneAble){
                        continue;
                    }
                    //大奖是否已经上限
                    CrossSignInDrawItemData itemData = itemDataMap.get(drawInfo.getRewardId());
                    if(itemData != null && itemData.getGetNum() >= drawInfo.getLimit()){
                        continue;
                    }
                }
                //玩家是否上限
                if(drawInfo.getRewardNumLimit() > 0){
                    int num = userData.getRewardMap().getOrDefault(drawInfo.getRewardId(), 0);
                    if(num >= drawInfo.getRewardNumLimit()){
                        continue;
                    }
                }
                poolList.add(drawInfo);
            }

            List<Integer> weightList = new ArrayList<>();
            for (SignInDrawDrawInfo drawInfo : poolList) {
                List<Integer> paramList = StringUtils.stringToIntegerList(drawInfo.getTrueWeight(), "\\|");
                weightList.add(paramList.get(valueType));
            }

            int idx = RandomHelper.getRandomIndexByWeight(weightList, random);
            drawDrawInfo = poolList.get(idx);
            if(drawDrawInfo.getLimit() > 0 || drawDrawInfo.getIsMonitor() > 0){
                CrossSignInDrawItemData itemData = itemDataMap.get(drawDrawInfo.getRewardId());
                if(itemData == null){
                    itemData = new CrossSignInDrawItemData();
                    itemData.setActivityId(activityInfo.getActivityId());
                    itemData.setRewardId(drawDrawInfo.getRewardId());
                    itemData.setInsertOption();
                    itemDataMap.put(itemData.getRewardId(), itemData);
                }
                if(drawDrawInfo.getLimit() > 0){
                    //防止太多数据
                    itemData.getUidList().add(uid);
                }
                itemData.setGetNum(1 + itemData.getGetNum());
            }
            int num = userData.getRewardMap().getOrDefault(drawDrawInfo.getRewardId(), 0);
            userData.getRewardMap().put(drawDrawInfo.getRewardId(), num + 1);
            userData.setUpdateOption();

            SignInDrawProto.CrossSignInDrawGoRespMsg.Builder respMsg = SignInDrawProto.CrossSignInDrawGoRespMsg.newBuilder();
            respMsg.setRet(0);
            respMsg.setRewardId(drawDrawInfo.getRewardId());
            MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_SIGN_IN_DRAW_DRAW_FROM_CROSS, respMsg));
        }

        if(drawDrawInfo.getIsNotice() == 1){
            SignInDrawNoticeData noticeData = new SignInDrawNoticeData();
            noticeData.setActivityId(activityInfo.getActivityId());
            noticeData.setUserId(playerId);
            noticeData.setNickName(baseInfo.getNickName());
            noticeData.setParam("");
            noticeData.setServerId(baseInfo.getServerId());
            noticeData.setReward(drawDrawInfo.getReward());
            noticeData.setGetTime(System.currentTimeMillis());
            noticeData.setInsertOption();
            synchronized (noticeDataList){
                noticeDataList.add(noticeData);
                while (noticeDataList.size() > config.getANNOUNCEMENT_QUANTITY()){
                    noticeDataList.remove(0);
                }
            }
        }
    }

    private CrossSignInDrawUserData getUserData(String uid) {
        CrossSignInDrawUserData userData = userDataMap.get(uid);
        if(userData == null){
            synchronized (userDataMap){
                userData = userDataMap.get(uid);
                if(userData == null){
                    userData = new CrossSignInDrawUserData();
                    userData.setActivityId(activityInfo.getActivityId());
                    userData.setUid(uid);
                    userData.setRewardMap(new HashMap<>());
                    userData.setInsertOption();
                    userDataMap.put(uid, userData);
                }
            }
        }
        return userData;
    }

    public SignInDrawActivity(ActivityInfo activityInfo) {
        this.activityInfo = activityInfo;
    }

    public void addDrawNotice(long serverId, long playerId, List<SignInDrawProto.SignInDrawNoticeMsg> noticeList) {
        synchronized (noticeDataList){
            for (SignInDrawProto.SignInDrawNoticeMsg noticeMsg : noticeList) {
                SignInDrawNoticeData noticeData = new SignInDrawNoticeData();
                noticeData.setActivityId(activityInfo.getActivityId());
                noticeData.setGetTime(noticeMsg.getTime());
                noticeData.setServerId(serverId);
                noticeData.setUserId(playerId);
                noticeData.setNickName(noticeMsg.getNickName());
                noticeData.setReward(noticeMsg.getReward());
                noticeData.setParam(noticeMsg.getValue() + "");
                noticeData.setInsertOption();
                noticeDataList.add(noticeData);
            }
            while (noticeDataList.size() > config.getANNOUNCEMENT_QUANTITY()){
                noticeDataList.remove(0);
            }
        }
    }

    public SignInDrawProto.SignInDrawNoticeRespMsg.Builder getNoticeList() {

        SignInDrawProto.SignInDrawNoticeRespMsg.Builder respMsg = SignInDrawProto.SignInDrawNoticeRespMsg.newBuilder();

        List<SignInDrawNoticeData> list = noticeDataList;
        if(list != null){
            for (int i = 0; i < list.size(); i++) {
                SignInDrawProto.SignInDrawNoticeMsg.Builder builder = SignInDrawProto.SignInDrawNoticeMsg.newBuilder();
                SignInDrawNoticeData noticeData = list.get(i);
                builder.setTime(noticeData.getGetTime());
                builder.setReward(noticeData.getReward());
                builder.setServerId(noticeData.getServerId());
                builder.setNickName(noticeData.getNickName());
                builder.setValue(0);
                respMsg.addNotice(builder);
            }
        }
        respMsg.setRet(0);
        return respMsg;
    }


    public void save(){

        for (int i = 0; i < noticeDataList.size(); i++) {
            SignInDrawNoticeData noticeData = noticeDataList.get(i);
            if(noticeData.isInsertOption()){
                new SignInDrawNoticeDataDaoImpl().add(noticeData);
            }else if(noticeData.isUpdateOption()){

            }
        }

        if(itemDataMap != null){
            for (Map.Entry<Integer, CrossSignInDrawItemData> entry : itemDataMap.entrySet()) {
                CrossSignInDrawItemData data = entry.getValue();
                if(data.isInsertOption()){
                    new CrossSignInDrawItemDataDaoImpl().add(data);
                }else if(data.isUpdateOption()){
                    new CrossSignInDrawItemDataDaoImpl().update(data);
                }
            }
        }

        if(userDataMap != null){
            for (Map.Entry<String, CrossSignInDrawUserData> entry : userDataMap.entrySet()) {
                CrossSignInDrawUserData data = entry.getValue();
                if(data.isInsertOption()){
                    new CrossSignInDrawUserDataDaoImpl().add(data);
                }else if(data.isUpdateOption()){
                    new CrossSignInDrawUserDataDaoImpl().update(data);
                }
            }
        }

    }



    public ActivityInfo getActivityInfo() {
        return activityInfo;
    }

    public void setActivityInfo(ActivityInfo activityInfo) {
        this.activityInfo = activityInfo;
    }

    public List<SignInDrawNoticeData> getNoticeDataList() {
        return noticeDataList;
    }

    public void setNoticeDataList(List<SignInDrawNoticeData> noticeDataList) {
        this.noticeDataList = noticeDataList;
    }

    public static long getDiffDayNum(long time) {
        long todayZeroTime = DateHelper.getTodayZeroTimeStamp() / 1000;
        long zeroTime = DateHelper.getZeroTimeStamp(time) / 1000;
        return (todayZeroTime - zeroTime) / DateHelper.DAY_SECONDS + 1;
    }
}
